/*
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <devmon/driver_abi.h>
#include <dlfcn.h>
#include <gtest/gtest.h>
#include <test_utilities/test_base.h>
#include <mc/common.h>

#include "test_hi182x_common.h"

using namespace dev;

namespace drivers {
namespace pcie_nic_card {
namespace hisi {
namespace test {

// ========================= 驱动注册功能测试 =========================

TEST_F(Hi182xAbiTest, register_device_driver_success) {
    // 目标：验证hi182x驱动注册成功，并返回正确数量的设备类型
    // 验证驱动注册返回3种设备类型
    EXPECT_EQ(m_devices.size(), 3);
    
    // 验证包含网卡设备类型
    EXPECT_TRUE(m_devices.find("PCIeNicCard") != m_devices.end());
    
    // 验证包含网口设备类型
    EXPECT_TRUE(m_devices.find("NicPort") != m_devices.end());
    
    // 验证包含光模块设备类型
    EXPECT_TRUE(m_devices.find("OpticalTransceiver") != m_devices.end());
}

TEST_F(Hi182xAbiTest, device_driver_structure_validation) {
    // 目标：验证每个设备驱动的ABI接口完整性
    for (const auto& [device_name, device_driver] : m_devices) {
        // 验证设备名称非空
        EXPECT_FALSE(std::string(device_driver->device_name).empty());
        
        // 验证构造函数指针有效
        EXPECT_TRUE(device_driver->ctor != nullptr);
        
        // 验证初始化函数指针有效
        EXPECT_TRUE(device_driver->init != nullptr);
        
        // 验证启动函数指针有效
        EXPECT_TRUE(device_driver->start != nullptr);
        
        // 验证停止函数指针有效
        EXPECT_TRUE(device_driver->stop != nullptr);
    }
}

// ========================= 错误处理测试 =========================

TEST_F(Hi182xAbiTest, device_pcienicard_with_null_device) {
    // 目标：验证PCIeNicCard设备对空指针参数的错误处理能力
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);

    // 测试：传入nullptr设备名称，应返回nullptr
    void* device = device_driver->ctor(&m_test_service, nullptr);
    EXPECT_EQ(device, nullptr);

    // 测试：传入nullptr服务指针，应返回nullptr
    device = device_driver->ctor(nullptr, "hi182x_card_null_params");
    EXPECT_EQ(device, nullptr);

    // 测试：init函数传入nullptr设备指针，应返回错误
    status_t init_ret = device_driver->init(nullptr, nullptr, nullptr);
    EXPECT_EQ(init_ret, STATUS_ERROR);

    // 测试：start函数传入nullptr设备指针，应返回错误
    status_t start_ret = device_driver->start(nullptr);
    EXPECT_EQ(start_ret, STATUS_ERROR);

    // 测试：stop函数传入nullptr设备指针，应返回错误
    status_t stop_ret = device_driver->stop(nullptr);
    EXPECT_EQ(stop_ret, STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, device_networkport_with_null_params) {
    // 目标：验证NicPort设备对空指针参数的错误处理能力
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);

    // 测试：传入nullptr设备名称，应返回nullptr
    void* device = device_driver->ctor(&m_test_service, nullptr);
    EXPECT_EQ(device, nullptr);

    // 测试：传入nullptr服务指针，应返回nullptr
    device = device_driver->ctor(nullptr, "hi182x_port_null_params");
    EXPECT_EQ(device, nullptr);

    // 测试：init函数传入nullptr，应返回错误
    status_t init_ret = device_driver->init(nullptr, nullptr, nullptr);
    EXPECT_EQ(init_ret, STATUS_ERROR);

    // 测试：start函数传入nullptr，应返回错误
    status_t start_ret = device_driver->start(nullptr);
    EXPECT_EQ(start_ret, STATUS_ERROR);

    // 测试：stop函数传入nullptr，应返回错误
    status_t stop_ret = device_driver->stop(nullptr);
    EXPECT_EQ(stop_ret, STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, device_opticalmodule_with_null_params) {
    // 目标：验证OpticalTransceiver设备对空指针参数的错误处理能力
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);

    // 测试：传入nullptr设备名称，应返回nullptr
    void* device = device_driver->ctor(&m_test_service, nullptr);
    EXPECT_EQ(device, nullptr);

    // 测试：传入nullptr服务指针，应返回nullptr
    device = device_driver->ctor(nullptr, "hi182x_optical_module_null_params");
    EXPECT_EQ(device, nullptr);

    // 测试：init函数传入nullptr，应返回错误
    status_t init_ret = device_driver->init(nullptr, nullptr, nullptr);
    EXPECT_EQ(init_ret, STATUS_ERROR);

    // 测试：start函数传入nullptr，应返回错误
    status_t start_ret = device_driver->start(nullptr);
    EXPECT_EQ(start_ret, STATUS_ERROR);

    // 测试：stop函数传入nullptr，应返回错误
    status_t stop_ret = device_driver->stop(nullptr);
    EXPECT_EQ(stop_ret, STATUS_ERROR);
}

// ========================= 多设备并发测试 =========================

TEST_F(Hi182xAbiTest, multiple_devices_creation) {
    // 目标：验证系统支持同时创建多个不同类型的设备实例
    // 场景：模拟多网卡、多网口、多光模块的真实使用场景
    std::vector<driver_handle_t> pcie_nic_card_devices;
    std::vector<driver_handle_t> network_port_devices;
    std::vector<driver_handle_t> optical_module_devices;

    // 创建3个PCIeNicCard设备实例
    auto card_driver = m_devices["PCIeNicCard"];
    for (int i = 0; i < 3; ++i) {
        std::string device_name = "hi182x_card_" + std::to_string(i);
        auto        device      = card_driver->ctor(&m_test_service, device_name.c_str());
        ASSERT_TRUE(device != nullptr);
        pcie_nic_card_devices.push_back(device);
    }

    // 创建3个NetworkPort设备实例
    auto port_driver = m_devices["NicPort"];
    for (int i = 0; i < 3; ++i) {
        std::string device_name = "hi182x_port_" + std::to_string(i);
        auto        device      = port_driver->ctor(&m_test_service, device_name.c_str());
        ASSERT_TRUE(device != nullptr);
        network_port_devices.push_back(device);
    }

    // 创建3个OpticalModule设备实例
    auto om_driver = m_devices["OpticalTransceiver"];
    for (int i = 0; i < 3; ++i) {
        std::string device_name = "hi182x_om_" + std::to_string(i);
        auto        device      = om_driver->ctor(&m_test_service, device_name.c_str());
        ASSERT_TRUE(device != nullptr);
        optical_module_devices.push_back(device);
    }

    // 验证所有设备创建成功
    EXPECT_EQ(pcie_nic_card_devices.size(), 3);
    EXPECT_EQ(network_port_devices.size(), 3);
    EXPECT_EQ(optical_module_devices.size(), 3);
}

// ========================= 异常处理测试 =========================

TEST_F(Hi182xAbiTest, create_hi182x_card_exception_handling) {
    // 目标：验证创建PCIeNicCard设备时的异常处理
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);
    
    // 测试：正常创建应该成功
    auto device = device_driver->ctor(&m_test_service, "hi182x_card_exception_test");
    ASSERT_TRUE(device != nullptr);
    
    // 清理
    device_driver->stop(device);
}

TEST_F(Hi182xAbiTest, init_hi182x_card_with_invalid_csr) {
    // 目标：验证使用无效CSR对象初始化设备时的错误处理
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_card_invalid_csr");
    ASSERT_TRUE(device != nullptr);
    
    // 创建无效的CSR对象（空字典）
    mc::mutable_dict invalid_csr;
    auto connector = create_test_connector(1, 1, 1);
    
    // 初始化应该能够处理无效CSR（可能返回false或抛出异常）
    status_t ret = device_driver->init(device, &invalid_csr, &connector);
    // 根据实际实现，可能是STATUS_OK或STATUS_ERROR
    EXPECT_TRUE(ret == STATUS_OK || ret == STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, init_hi182x_port_with_invalid_csr) {
    // 目标：验证使用无效CSR对象初始化网口设备时的错误处理
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_port_invalid_csr");
    ASSERT_TRUE(device != nullptr);
    
    mc::mutable_dict invalid_csr;
    auto connector = create_test_connector(1, 1, 1);
    
    status_t ret = device_driver->init(device, &invalid_csr, &connector);
    EXPECT_TRUE(ret == STATUS_OK || ret == STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, init_hi182x_optical_module_with_invalid_csr) {
    // 目标：验证使用无效CSR对象初始化光模块设备时的错误处理
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_om_invalid_csr");
    ASSERT_TRUE(device != nullptr);
    
    mc::mutable_dict invalid_csr;
    auto connector = create_test_connector(1, 1, 1);
    
    status_t ret = device_driver->init(device, &invalid_csr, &connector);
    EXPECT_TRUE(ret == STATUS_OK || ret == STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, init_hi182x_card_with_null_connector) {
    // 目标：验证使用nullptr connector初始化设备时的错误处理
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_card_null_connector");
    ASSERT_TRUE(device != nullptr);
    
    mc::mutable_dict csr;
    status_t ret = device_driver->init(device, &csr, nullptr);
    EXPECT_EQ(ret, STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, init_hi182x_port_with_null_connector) {
    // 目标：验证使用nullptr connector初始化网口设备时的错误处理
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_port_null_connector");
    ASSERT_TRUE(device != nullptr);
    
    mc::mutable_dict csr;
    status_t ret = device_driver->init(device, &csr, nullptr);
    EXPECT_EQ(ret, STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, init_hi182x_optical_module_with_null_connector) {
    // 目标：验证使用nullptr connector初始化光模块设备时的错误处理
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_om_null_connector");
    ASSERT_TRUE(device != nullptr);
    
    mc::mutable_dict csr;
    status_t ret = device_driver->init(device, &csr, nullptr);
    EXPECT_EQ(ret, STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, start_hi182x_card_without_init) {
    // 目标：验证未初始化就启动设备的行为
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_card_no_init");
    ASSERT_TRUE(device != nullptr);
    
    // 未初始化就启动，应该返回STATUS_OK（根据实现）
    status_t ret = device_driver->start(device);
    EXPECT_EQ(ret, STATUS_OK);
    
    device_driver->stop(device);
}

TEST_F(Hi182xAbiTest, start_hi182x_port_without_init) {
    // 目标：验证未初始化就启动网口设备的行为
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_port_no_init");
    ASSERT_TRUE(device != nullptr);
    
    status_t ret = device_driver->start(device);
    // 根据实现，可能返回STATUS_OK或STATUS_ERROR
    EXPECT_TRUE(ret == STATUS_OK || ret == STATUS_ERROR);
    
    device_driver->stop(device);
}

TEST_F(Hi182xAbiTest, start_hi182x_optical_module_without_init) {
    // 目标：验证未初始化就启动光模块设备的行为
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_om_no_init");
    ASSERT_TRUE(device != nullptr);
    
    status_t ret = device_driver->start(device);
    EXPECT_EQ(ret, STATUS_OK);
    
    device_driver->stop(device);
}

TEST_F(Hi182xAbiTest, stop_hi182x_card_without_start) {
    // 目标：验证未启动就停止设备的行为
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_card_no_start");
    ASSERT_TRUE(device != nullptr);
    
    // 未启动就停止，应该返回STATUS_OK
    status_t ret = device_driver->stop(device);
    EXPECT_EQ(ret, STATUS_OK);
}

TEST_F(Hi182xAbiTest, stop_hi182x_port_without_start) {
    // 目标：验证未启动就停止网口设备的行为
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_port_no_start");
    ASSERT_TRUE(device != nullptr);
    
    status_t ret = device_driver->stop(device);
    EXPECT_EQ(ret, STATUS_OK);
}

TEST_F(Hi182xAbiTest, stop_hi182x_optical_module_without_start) {
    // 目标：验证未启动就停止光模块设备的行为
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_om_no_start");
    ASSERT_TRUE(device != nullptr);
    
    status_t ret = device_driver->stop(device);
    EXPECT_EQ(ret, STATUS_OK);
}

TEST_F(Hi182xAbiTest, device_lifecycle_multiple_start_stop) {
    // 目标：验证设备多次启动和停止的稳定性
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);
    
    auto device = device_driver->ctor(&m_test_service, "hi182x_card_multiple");
    ASSERT_TRUE(device != nullptr);
    
    auto csr = mc::mutable_dict{{"SystemId", 1}};
    auto connector = create_test_connector(1, 1, 1);
    
    EXPECT_EQ(device_driver->init(device, &csr, &connector), STATUS_OK);
    
    // 多次启动和停止
    for (int i = 0; i < 3; ++i) {
        EXPECT_EQ(device_driver->start(device), STATUS_OK);
        EXPECT_EQ(device_driver->stop(device), STATUS_OK);
    }
}

TEST_F(Hi182xAbiTest, register_device_driver_count_validation) {
    // 目标：验证驱动注册返回的设备数量正确
    device_driver_t* devices = nullptr;
    uint8_t count = 0;
    
    // 通过ABI获取设备驱动
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);
    
    // 验证设备数量为3（PCIeNicCard, NicPort, OpticalTransceiver）
    EXPECT_EQ(m_devices.size(), 3);
}

} // namespace test
} // namespace hisi
} // namespace pcie_nic_card
} // namespace drivers
